﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IWMAG.Scripting.AST.ObjectModel;
using IWMAG.Scripting.Types;
using IWMAG.Scripting.AST.TerminalExpressions;
using IWMAG.Scripting.Interpreter;
using IWMAG.Scripting.Compiler.UserInfo;
using System.Diagnostics;

namespace IWMAG.Scripting.AST.Statements {
    internal class WaitStatement : CodeStatement {
        public CodeExpression Value;

        public WaitStatement(Compiler.Lexeme l, CodeExpression val) : base(l) {
            Value = val;
        }

        public override void Verify(Helpers.CompileTable sym, List<Compiler.IUserInfo> error) {
            Value.Verify(sym, error);

            if (!sym.Lookahead.Contains(GetType())) {
                Debug.Fail("The function didn't declare a wait handler. This should never happen.");
            } else {
                sym.Lookahead[GetType()]();
            }

            if (Value.TypeOf() != CodeType.Int) {
                SendError(error, Rules.WaitStatementArgumentMustBeInteger);
            }
        }

        public override IEnumerable<Continuation> Execute(ScriptEngine engine, Helpers.RuntimeTable sym) {
            Reference<RunValue> res = new Reference<RunValue>(RunValue.NoValue);

            foreach (Continuation wait in Value.ValueOf(engine, sym, res)) {
                yield return wait;
            }

            yield return new Continuation(Continuation.Token.Wait, res.ReferencedValue.IntValue);
        }
    }
}
